#include "gridtest.h"

/*Registry this TestSuite to theTestFactoryRegistry*/
CPPUNIT_TEST_SUITE_REGISTRATION (GridTest);

void GridTest::setUp() {
	SG_init();
}

void GridTest::testConstructorDestructor() {
	Grid *g = NULL;
	g = new Grid("grid_1");
	
	CPPUNIT_ASSERT_EQUAL(g->getNumberOfSites(), 0);
	CPPUNIT_ASSERT_EQUAL(g->getNumberOfRoutes(), 0);	
	CPPUNIT_ASSERT_EQUAL(g->getNumberOfLinks(), -1);	
	
	delete g;	
}

void GridTest::testAddSiteException() { fprintf(stderr,">>> GridTest::testAddSiteException()\n");
	Grid *g = NULL;
	g = new Grid("grid_1");	
	
	try {
		g->addSite("Fake_site", "intraBW",0, "interLat",0, "interBW", 0 , "interBWLIM",0, "intraBWERR", "interLATERR", "interBWERR", "intraBWFor", "interLATFor", "interBWFor", "interBWLIMFor");
		CPPUNIT_FAIL("An exception should be throwed!!");
	} catch (std::runtime_error &e) {
	}
	CPPUNIT_ASSERT_EQUAL(g->getNumberOfSites(), 0);
	CPPUNIT_ASSERT_EQUAL(g->getNumberOfRoutes(), 0);	
	CPPUNIT_ASSERT_EQUAL(g->getNumberOfLinks(), -1);	
	
	delete g;
}

void GridTest::testAddOneSite() { fprintf(stderr,">>> GridTest::testAddOneSite()\n");

	Grid *g = NULL;
	g = new Grid("grid_1");

//	FIXED SITE
//	g->addSite("site1", 100, Link::MINIMUM_LATENCY, 2, 10);

	g->addSite("site1", 100, -1, -1, -1); //first site added

	CPPUNIT_ASSERT_EQUAL(g->getNumberOfSites(), 1);
	CPPUNIT_ASSERT_EQUAL(g->getNumberOfRoutes(), 1);	
	CPPUNIT_ASSERT_EQUAL(g->getNumberOfLinks(), 0);	
	
	SG_Resource	_internalroute = g->getRouteToSite(0);
	Link *l = NULL;
	try {
		l = g->getLinkByIndex(0);
		CPPUNIT_FAIL("An exception should be throwed!");
	} catch (std::runtime_error &e){
		//Pass
	}
	
	CPPUNIT_ASSERT(!strcmp("internalroute_site1", SG_getResourceName(_internalroute)));
	
	//TRACE-BASED SITE
	Grid *g2  = new Grid("grid_2");	
	g2->addSite("site1","../data/traces/cputrace.0",0,NULL, 0, NULL,0, NULL,0, "../data/traces/cputrace.0", "../data/traces/cputrace.0", "../data/traces/cputrace.0"); //first site added

	SG_Resource	_internalroute2 = g2->getRouteToSite(0);
	
	Link *l2 = NULL;
	try {
		l2 = g2->getLinkByIndex(0);
		CPPUNIT_FAIL("An exception should be throwed!");
	} catch (std::runtime_error &e){
		//Pass
	}

	CPPUNIT_ASSERT(!strcmp("internalroute_site1", SG_getResourceName(_internalroute2)));

	
	delete g;
	delete g2;


}

void GridTest::testAddSite() { fprintf(stderr,">>> GridTest::testAddSite()\n");

	Grid *g = new Grid("grid1");
	g->addSite("site0","../data/traces/cputrace.0",0,NULL, 0, NULL,0, NULL,0, "../data/traces/cputrace.0", "../data/traces/cputrace.0", "../data/traces/cputrace.0"); //first site added	
	g->addSite("site1","../data/traces/cputrace.0",0,"../data/traces/cputrace.0", 0, "../data/traces/cputrace.0",0, "../data/traces/cputrace.0",0, "../data/traces/cputrace.0", "../data/traces/cputrace.0", "../data/traces/cputrace.0", "../data/traces/cputrace.0", "../data/traces/cputrace.0", "../data/traces/cputrace.0", "../data/traces/cputrace.0");
	g->addSite("site2","../data/traces/cputrace.0",0,"../data/traces/cputrace.0", 0, "../data/traces/cputrace.0",0, "../data/traces/cputrace.0",0, "../data/traces/cputrace.0", "../data/traces/cputrace.0", "../data/traces/cputrace.0", "../data/traces/cputrace.0", "../data/traces/cputrace.0", "../data/traces/cputrace.0", "../data/traces/cputrace.0");		

	CPPUNIT_ASSERT_EQUAL(g->getNumberOfSites(), 3);
	CPPUNIT_ASSERT_EQUAL(g->getNumberOfRoutes(), 3);	
	CPPUNIT_ASSERT_EQUAL(g->getNumberOfLinks(), 2);	
	
	CPPUNIT_ASSERT(!strcmp("interlink_site0_site1",g->getLinkByIndex(0)->getName()));
	CPPUNIT_ASSERT(!strcmp("interlink_site0_site2",g->getLinkByIndex(1)->getName()));
	
	CPPUNIT_ASSERT(!strcmp("internalroute_site0",SG_getResourceName(g->getRouteToSite(0))));
	CPPUNIT_ASSERT(!strcmp("route_site0_site1",SG_getResourceName(g->getRouteToSite(1))));	
	CPPUNIT_ASSERT(!strcmp("route_site0_site2",SG_getResourceName(g->getRouteToSite(2))));		
	
	CPPUNIT_ASSERT(!strcmp("site0",g->getSiteByDomain("site0")->getDomain()));
	CPPUNIT_ASSERT(!strcmp("site1",g->getSiteByDomain("site1")->getDomain()));	
	CPPUNIT_ASSERT(!strcmp("site2",g->getSiteByDomain("site2")->getDomain()));	
	
	try {
		g->getSiteByDomain("siteNOTFOUND");		
		CPPUNIT_FAIL("An exception should be throwed!!");
	} catch (std::runtime_error &e) {
		//Pass
	}
	

	delete g;
	
}

void GridTest::testGetBottleneckLink() { fprintf(stderr,">>> GridTest::testGetBottleneckLink()\n");
	//linktrace > cputrace.0
	
	Grid *g = new Grid("grid1");
	g->addSite("site0","../data/traces/linkbw1Mbit",0 , NULL, 0, NULL, 0, NULL, 0, "../data/traces/cputrace.0", "../data/traces/cputrace.0", "../data/traces/cputrace.0"); //first site added	
	g->addSite("site1","../data/traces/cputrace.0",0,"../data/traces/cputrace.0", 0, "../data/traces/cputrace.0",0, "../data/traces/cputrace.0",0, "../data/traces/cputrace.0", "../data/traces/cputrace.0", "../data/traces/cputrace.0", "../data/traces/cputrace.0", "../data/traces/cputrace.0", "../data/traces/cputrace.0", "../data/traces/cputrace.0");
	g->addSite("site2","../data/traces/cputrace.0",0,"../data/traces/cputrace.0", 0, "../data/traces/cputrace.0",0, "../data/traces/cputrace.0",0, "../data/traces/cputrace.0", "../data/traces/cputrace.0", "../data/traces/cputrace.0", "../data/traces/cputrace.0", "../data/traces/cputrace.0", "../data/traces/cputrace.0", "../data/traces/cputrace.0");		
	
	CPPUNIT_ASSERT(!strcmp(g->getBottleneckLinkOfRouteToSite(0)->getName(), "intralink_site0"));
	CPPUNIT_ASSERT(!strcmp(g->getBottleneckLinkOfRouteToSite(1)->getName(), "interlink_site0_site1"));
	CPPUNIT_ASSERT(!strcmp(g->getBottleneckLinkOfRouteToSite(2)->getName(), "interlink_site0_site2"));	
	
	try {
		g->getBottleneckLinkOfRouteToSite(-1);
		CPPUNIT_FAIL("An exception should be throwed!");
	} catch (std::runtime_error &e) {
	}
}

void GridTest::testGridIsBusy() { fprintf(stderr,">>> GridTest::testGridIsBusy()\n");

	SG_Task fakeTask = SG_newTask (SG_COMPUTATION, "task1", 100, NULL);
	SG_Task fakeTask2 = SG_newTask (SG_COMPUTATION, "task2", 100, NULL);
	SG_Task fakeTask3 = SG_newTask (SG_COMPUTATION, "task3", 100, NULL);
	SG_Task fakeTask4 = SG_newTask (SG_COMPUTATION, "task4", 100, NULL);

	Grid *g = new Grid("grid1");
	
	CPPUNIT_ASSERT(g->isTotallyBusy()==true);		
	
	g->addSite("site0","../data/traces/linkbw1Mbit",0 , NULL, 0, NULL, 0, NULL, 0, "../data/traces/linkbw1Mbit", "../data/traces/cputrace.0", "../data/traces/cputrace.0", "../data/traces/cputrace.0"); //first site added	
	g->addSite("site1","../data/traces/linkbw1Mbit",0,"../data/traces/cputrace.0", 0, "../data/traces/cputrace.0",0, "../data/traces/cputrace.0",0, "../data/traces/linkbw1Mbit", "../data/traces/cputrace.0", "../data/traces/cputrace.0", "../data/traces/cputrace.0", "../data/traces/cputrace.0", "../data/traces/cputrace.0", "../data/traces/cputrace.0");
	g->addSite("site2","../data/traces/linkbw1Mbit",0,"../data/traces/cputrace.0", 0, "../data/traces/cputrace.0",0, "../data/traces/cputrace.0",0, "../data/traces/linkbw1Mbit", "../data/traces/cputrace.0", "../data/traces/cputrace.0", "../data/traces/cputrace.0", "../data/traces/cputrace.0", "../data/traces/cputrace.0", "../data/traces/cputrace.0");		

	CPPUNIT_ASSERT(g->isTotallyBusy()==true);			
	
	g->getSiteByIndex(1)->addProcessor(1, 1);
	g->getSiteByIndex(1)->addProcessor(2,0.9);
	SG_scheduleTaskOnResource(fakeTask, g->getSiteByIndex(1)->getProcessorByIndex(0)->getSGResource());


	g->getSiteByIndex(2)->addProcessor(1, 1);
	g->getSiteByIndex(2)->addProcessor(2,0.9);
	SG_scheduleTaskOnResource(fakeTask3, g->getSiteByIndex(2)->getProcessorByIndex(0)->getSGResource());

	CPPUNIT_ASSERT(g->isTotallyBusy()==false);	
	SG_scheduleTaskOnResource(fakeTask2, g->getSiteByIndex(1)->getProcessorByIndex(1)->getSGResource());
	CPPUNIT_ASSERT(g->isTotallyBusy()==false);	
	SG_scheduleTaskOnResource(fakeTask4, g->getSiteByIndex(2)->getProcessorByIndex(1)->getSGResource());
	
	CPPUNIT_ASSERT(g->isTotallyBusy()==true);

}

void GridTest::tearDown() {

	SG_clear();
}

void GridTest::testTotalNumberOfProcessors() { fprintf(stderr,">>> GridTest::testTotalNumberOfProcessors()\n");
	Grid *g = new Grid("grid1");
	
	CPPUNIT_ASSERT(g->isTotallyBusy()==true);		
	
	g->addSite("site0","../data/traces/linkbw1Mbit",0 , NULL, 0, NULL, 0, NULL, 0, "../data/traces/linkbw1Mbit", "../data/traces/cputrace.0", "../data/traces/cputrace.0", "../data/traces/cputrace.0"); //first site added	
	g->addSite("site1","../data/traces/linkbw1Mbit",0,"../data/traces/cputrace.0", 0, "../data/traces/cputrace.0",0, "../data/traces/cputrace.0",0, "../data/traces/linkbw1Mbit", "../data/traces/cputrace.0", "../data/traces/cputrace.0", "../data/traces/cputrace.0", "../data/traces/cputrace.0", "../data/traces/cputrace.0", "../data/traces/cputrace.0");
	g->addSite("site2","../data/traces/linkbw1Mbit",0,"../data/traces/cputrace.0", 0, "../data/traces/cputrace.0",0, "../data/traces/cputrace.0",0, "../data/traces/linkbw1Mbit", "../data/traces/cputrace.0", "../data/traces/cputrace.0", "../data/traces/cputrace.0", "../data/traces/cputrace.0", "../data/traces/cputrace.0", "../data/traces/cputrace.0");		

	CPPUNIT_ASSERT(g->getTotalNumberOfProcessors()==0);			
	
	g->getSiteByIndex(1)->addProcessor(1, 1);
	g->getSiteByIndex(1)->addProcessor(2,0.9);

	CPPUNIT_ASSERT(g->getTotalNumberOfProcessors()==2);			

	g->getSiteByIndex(2)->addProcessor(1, 1);
	g->getSiteByIndex(2)->addProcessor(2,0.9);
	
	CPPUNIT_ASSERT(g->getTotalNumberOfProcessors()==4);				
	
}
